//
//  JRGridCollectionView.h
//  SafeAreaTest
//
//  Created by dingjiarui on 2017/11/16.
//  Copyright © 2017年 dingjiarui. All rights reserved.
//


#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN

typedef NSString * _Nonnull (^__nullable JRGridCollectionViewDequeueReusableCellBlock)(NSIndexPath * _Nonnull indexPath, id  _Nonnull item);
typedef void (^__nullable JRGridCollectionViewCellConfigureBlock)(NSIndexPath * _Nonnull indexPath, id _Nonnull item, UICollectionViewCell * _Nonnull cell);
typedef CGSize (^__nullable JRGridCollectionViewSizeForItemBlock)(NSIndexPath * _Nonnull indexPath, id _Nonnull item);
typedef void (^__nullable JRGridCollectionViewDidSelectItemAtIndexPathBlock)(NSIndexPath * _Nonnull indexPath, id _Nonnull item);

typedef NSString * _Nonnull (^__nullable JRGridCollectionViewDequeueReusableSupplementaryViewlBlock)(NSIndexPath * _Nonnull indexPath, NSString * _Nonnull kind);
typedef void (^__nullable JRGridCollectionViewSupplementaryViewConfigureBlock)(NSIndexPath * _Nonnull indexPath, UICollectionReusableView * _Nonnull view);


@protocol JRGridCollectionViewDelegate;

@interface JRGridCollectionView : UIView

/** 必须为二维数组 @[@[obj, obj, ...], ...] */
@property (nonatomic, strong) NSArray <NSArray *> *dataSources;


/**
 初始化

 @param aCellIdentifier cell标记回调
 @param aConfigureCell cell设置回调
 @param aDidSelectItemAtIndexPath 点击回调
 */
- (void)callbackCellIdentifier:(JRGridCollectionViewDequeueReusableCellBlock)aCellIdentifier
                 configureCell:(JRGridCollectionViewCellConfigureBlock)aConfigureCell
      didSelectItemAtIndexPath:(JRGridCollectionViewDidSelectItemAtIndexPathBlock)aDidSelectItemAtIndexPath;


/**
 初始化 + item大小
 
 @param aCellIdentifier cell标记回调
 @param aConfigureCell cell设置回调
 @param aSizeForItem cell大小回调
 @param aDidSelectItemAtIndexPath 点击回调
 */
- (void)callbackCellIdentifier:(JRGridCollectionViewDequeueReusableCellBlock)aCellIdentifier
                 configureCell:(JRGridCollectionViewCellConfigureBlock)aConfigureCell
                   sizeForItem:(JRGridCollectionViewSizeForItemBlock)aSizeForItem
      didSelectItemAtIndexPath:(JRGridCollectionViewDidSelectItemAtIndexPathBlock)aDidSelectItemAtIndexPath;


/**
 初始化 + SupplementaryView
 
 @param aCellIdentifier cell标记回调
 @param aConfigureCell cell设置回调
 @param aDidSelectItemAtIndexPath 点击回调
 @param aSupplementaryViewIdentifier SupplementaryView标记回调
 @param aSupplementaryViewConfigureBlock SupplementaryView设置回调
 */
- (void)callbackCellIdentifier:(JRGridCollectionViewDequeueReusableCellBlock)aCellIdentifier
                 configureCell:(JRGridCollectionViewCellConfigureBlock)aConfigureCell
      didSelectItemAtIndexPath:(JRGridCollectionViewDidSelectItemAtIndexPathBlock)aDidSelectItemAtIndexPath
   supplementaryViewIdentifier:(JRGridCollectionViewDequeueReusableSupplementaryViewlBlock)aSupplementaryViewIdentifier
supplementaryViewConfigureBlock:(JRGridCollectionViewSupplementaryViewConfigureBlock)aSupplementaryViewConfigureBlock;


/**
 初始化 + item大小 + SupplementaryView
 
 @param aCellIdentifier cell标记回调
 @param aConfigureCell cell设置回调
 @param aSizeForItem cell大小回调
 @param aDidSelectItemAtIndexPath 点击回调
 @param aSupplementaryViewIdentifier SupplementaryView标记回调
 @param aSupplementaryViewConfigureBlock SupplementaryView设置回调
 */
- (void)callbackCellIdentifier:(JRGridCollectionViewDequeueReusableCellBlock)aCellIdentifier
                 configureCell:(JRGridCollectionViewCellConfigureBlock)aConfigureCell
                   sizeForItem:(JRGridCollectionViewSizeForItemBlock)aSizeForItem
      didSelectItemAtIndexPath:(JRGridCollectionViewDidSelectItemAtIndexPathBlock)aDidSelectItemAtIndexPath
   supplementaryViewIdentifier:(JRGridCollectionViewDequeueReusableSupplementaryViewlBlock)aSupplementaryViewIdentifier
supplementaryViewConfigureBlock:(JRGridCollectionViewSupplementaryViewConfigureBlock)aSupplementaryViewConfigureBlock;

#pragma mark - UICollectionView
@property (nonatomic, strong) UICollectionViewFlowLayout * _Nullable collectionViewLayout;
@property(nonatomic,getter=isPagingEnabled) BOOL          pagingEnabled __TVOS_PROHIBITED;// default NO. if YES, stop on multiples of view bounds
@property(nonatomic)         BOOL                         showsHorizontalScrollIndicator; // default YES. show indicator while we are tracking. fades out after tracking
@property(nonatomic)         BOOL                         showsVerticalScrollIndicator;   // default YES. show indicator while we are tracking. fades out after tracking

- (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(nullable UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier;

- (void)registerClass:(nullable Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(nullable UINib *)nib forSupplementaryViewOfKind:(NSString *)kind withReuseIdentifier:(NSString *)identifier;

- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated;

- (void)reloadData;

- (nullable UICollectionViewCell *)cellForItemAtIndexPath:(NSIndexPath *)indexPath;

- (void)performBatchUpdates:(void (NS_NOESCAPE ^ _Nullable)(void))updates completion:(void (^ _Nullable)(BOOL finished))completion; // allows multiple insert/delete/reload/move calls to be animated simultaneously. Nestable.

- (void)insertItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
- (void)deleteItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
- (void)reloadItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;

@property (nonatomic, strong, nullable) UIView *collectionHeaderView;                           // accessory view for above row content. default is nil. not to be confused with section header
@property (nonatomic, strong, nullable) UIView *collectionFooterView;                           // accessory view below content. default is nil. not to be confused with section footer

#pragma mark - UICollectionViewFlowLayout
@property (nonatomic) CGFloat minimumLineSpacing;
@property (nonatomic) CGFloat minimumInteritemSpacing;
@property (nonatomic) CGSize itemSize;
@property (nonatomic) CGSize estimatedItemSize NS_AVAILABLE_IOS(8_0); // defaults to CGSizeZero - setting a non-zero size enables cells that self-size via -preferredLayoutAttributesFittingAttributes:
@property (nonatomic) UICollectionViewScrollDirection scrollDirection; // default is UICollectionViewScrollDirectionVertical
@property (nonatomic) CGSize headerReferenceSize;
@property (nonatomic) CGSize footerReferenceSize;
@property (nonatomic) UIEdgeInsets sectionInset;
@property (nonatomic, readonly) NSArray<__kindof UICollectionViewCell *> *visibleCells;
@property (nonatomic, readonly) NSArray<NSIndexPath *> *indexPathsForVisibleItems;

#pragma mark - UIScrollView
@property(nonatomic)         BOOL                         bounces;                        // default YES. if YES, bounces past edge of content and back again
@property(nonatomic)         CGPoint                      contentOffset;                  // default CGPointZero
@property(nonatomic)         CGSize                       contentSize;                    // default CGSizeZero
@property(nonatomic)         UIEdgeInsets                 contentInset;                   // default UIEdgeInsetsZero. add additional scroll area around content
@property(nullable,nonatomic,weak) id<JRGridCollectionViewDelegate>        delegate;                       // default nil. weak reference
- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated;  // animate at constant velocity to new offset
- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated;         // scroll so rect is just visible (nearest edges). nothing if rect completely visible
- (nullable NSIndexPath *)indexPathForItemAtPoint:(CGPoint)point;

- (void)moveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath;


- (BOOL)beginInteractiveMovementForItemAtIndexPath:(NSIndexPath *)indexPath API_AVAILABLE(ios(9.0)); // returns NO if reordering was prevented from beginning - otherwise YES
- (void)updateInteractiveMovementTargetPosition:(CGPoint)targetPosition API_AVAILABLE(ios(9.0));
- (void)endInteractiveMovement API_AVAILABLE(ios(9.0));
- (void)cancelInteractiveMovement API_AVAILABLE(ios(9.0));

@end

@protocol JRGridCollectionViewDelegate<NSObject>

@optional
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;                                               // any offset changes

// called on start of dragging (may require some time and or distance to move)
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;
// called on finger up if the user dragged. velocity is in points/millisecond. targetContentOffset may be changed to adjust where the scroll view comes to rest
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset NS_AVAILABLE_IOS(5_0);
// called on finger up if the user dragged. decelerate is true if it will continue moving afterwards
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView;   // called on finger up as we are moving
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;      // called when scroll view grinds to a halt

- (BOOL)jrGridcollectionView:(JRGridCollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath;

- (void)jrGridcollectionView:(JRGridCollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath;
@end

NS_ASSUME_NONNULL_END
